﻿using System.Text.Json.Serialization;
using BCore.Identity.Users.Caching;
using Core.Caching;
using Core.Extensions;
using Core.Helpers;
using Core.Identity.Common.Interfaces.Common.Interfaces;
using Core.Infrastructure;
using Core.Models;
using Core.Uploads;
using MediatR;

namespace Core.Identity.Users.Features.Commands.UploadAvatar;

/// <summary>
/// 上传头像
/// </summary>
public class UploadAvatarCommand : ICacheInvalidatorRequest<Result<bool>>
{
    /// <summary>
    /// 用户唯一标识
    /// </summary>
    public Guid UserId { get; set; }

    /// <summary>
    /// 头像Base64
    /// </summary>
    public required string AvatarBase64 { get; set; }

    [JsonIgnore]
    public IEnumerable<string>? Tags => UsersCacheKey.Tags;
}
public class UploadAvatarCommandHandler(
    IIdentityDbContext dbContext,
    IUploadService uploadService,
    IBoilerplateFileProvider fileProvider) : IRequestHandler<UploadAvatarCommand, Result<bool>>
{

    public async Task<Result<bool>> Handle(UploadAvatarCommand request, CancellationToken cancellationToken)
    {
        var user = await dbContext.Users.FindAsync(request.UserId, cancellationToken);
        ExceptionHelper.ThrowIfNull(user, "数据不存在");

        var oldAvatar = string.Empty;
        if (user!.Avatar != null && !string.IsNullOrWhiteSpace(user!.Avatar.Url))
        {
            oldAvatar = user.Avatar.Url;
        }

        var avatarInfo = await uploadService.UploadFileAsync(request.AvatarBase64.ToFormFile(), "avatar");
        user.ChangeAvatar(avatarInfo.Src, avatarInfo.FileType);
        dbContext.Users.Update(user);

        var result = await dbContext.SaveChangesAsync(cancellationToken) > 0;

        if (result && !string.IsNullOrWhiteSpace(oldAvatar))
        {
            // 计算根目录（wwwroot）
            var rootPath = avatarInfo.FullSavePath.Replace(avatarInfo.Src.Replace("/", "\\"), "");

            // 拼出旧文件完整路径
            var deleteOldAvatar = Path.Combine(rootPath, oldAvatar.TrimStart('/').Replace("/", "\\"));

            fileProvider.DeleteFile(deleteOldAvatar);
        }

        return await Result<bool>.SucceedAsync(result, result, ["修改失败"]);
    }
}
